<template>
  <div class="lu-wrap">
    <!--fixed定位的时候显示timeline模块-->
    <Header :fixed="fixedLine" v-show="fixedLine"></Header>
    <Scroll ref="scroll" :probeType="3" :listenScroll="true" :bounce="false" @scroll="fixTimeline" :class="{scrollH:this.fixedLine}">
      <div class="pad40">
        <Header :fixed="fixedLine" id="defaultLUHeader"></Header>
        <div class="h328" v-show="fixedLine"></div>
      </div>
      <div class="lightup-wrap">
      <div id="lightbox" ref="lightstage"></div>
      </div>
      <Footer></Footer>
    </Scroll>
    <toast :open="toastVisible" :delay="false" :modal="modalFlag" @close="closeToast">
      <div slot="tipmes">
        <div v-show="modalFlag" class="rule-wrap">
          <h3>
            <i class="close-btn" @click.stop.prevent="closeToast"></i>
          </h3>
          <section>
            <TipScroll ref="scrollTip" :loadMore="false" :bounce="false">
              <div slot="defaultScroll">
                <p v-for="(i, index) in rules" :key="`lightRules${index}`">{{i}}</p>
              </div>
            </TipScroll>
          </section>
        </div>
        <div v-show="!modalFlag">{{!modalFlag && toastMes}}</div>
      </div>
    </toast>
  </div>
</template>

<script type="text/ecmascript-6">
  import * as PIXI from 'pixi.js';
  import TWEEN from 'pixi.js/tween';
  import Header from '../components/header';
  import Footer from '../components/footer';
  import BrightParticle from '../../../utils/brightParticles';
  import {requestLight} from '../../../mock/mock';
  import functionalTool from '../../../utils/functionTools';
  import toast from '../../../components/feedback/toast';
  import Scroll from '../../../components/scrollNew/scroll';
  import TipScroll from '../../../components/scroll/list';
  const [Application, Loader, Container, Sprite, Text, TextStyle, Tween] = [
    PIXI.Application,
    PIXI.loader,
    PIXI.Container,
    PIXI.Sprite,
    PIXI.Text,
    PIXI.TextStyle,
    TWEEN.Tween
  ];
  export default {
    name: 'lightUp',
    data () {
      return {
        toastVisible: !1,
        fixedLine: false,
        posY: 0,
        starTime: '',
        starOver: '',
        animate: true,
        pageIndex: 0,
        lotteryTime: '',
        lotteryOver: '',
        starWait: false,
        lotteryWait: false,
        modalFlag: !1,
        toastMes: '',
        chanceNum: 0,
        rules: [],
        accountId: functionalTool.getUrlParam('accountId'),
        city: functionalTool.getUrlParam('city'),
        lightData: {},
        activeInfo: {}
      };
    },
    mounted () {
      this.$root.eventBus.$on('rules', (r) => {
        this.rules = r.lightRule;
      });
      this.generateStage();
      this.$root.eventBus.$on('activeInfo', (r) => {
        this.activeInfo = r;
        this.lightData.lightNum = r.userLight;
        this.lightData.userNum = r.cityLight;
        this.lightData.chanceNum = r.userLightChance;
        this.lightData.btnNum = `(${r.userLightChance})次`;
        if (this.lightNum) {
          this.lightNum.text = this.lightData.lightNum;
          this.userNum.text = this.lightData.userNum;
          this.chanceNum = this.lightData.chanceNum;
          this.btnNum.text = this.lightData.btnNum;
        }
        // this.showTime();
      });
      this.$nextTick(() => {
        this.getOffsetH();
      })
    },
    methods: {
      // 获取初始渲染的时间轴距顶部距离
      getOffsetH () {
        let timelineOffsetH = document.getElementById('defaultLUHeader').getElementsByClassName('time-line');
        this.offtoplu = timelineOffsetH[0].offsetTop;
      },
      // 监听滚动条，当滚动的距离绝对值大于offtoplu的时候，timeline固定在窗口顶部
      fixTimeline (pos) {
        this.fixedLine = pos.y <= -this.offtoplu;
        // this.posY = pos.y <= -194 ? pos.y : 0
      },
      /*
      * 初始化构建场景stage
      * @param world (DOM) 场景wrapper
      * @param ratio (Number) 宽高比
      * @param WORLD_WIDTH (Number) 场景宽度
      * @param WORLD_HEIGHT (Number) 场景高度
      * @param SOURCE_WIDTH (Number) 设计稿宽度
      * @param SOURCE_HEIGHT (Number) 设计稿高度
      * @param SCALE (Number) 素材缩放比
      * @param app (Obj) PIXI实例
      * */
      generateStage () {
        const world = this.$refs.lightstage;
        const ratio = 1.473;
        let WorldWidth = window.getComputedStyle(world).width;
        WorldWidth = WorldWidth.substr(0, WorldWidth.length - 2);
        let WorldHeight = ratio * WorldWidth;
        let dpr = window.devicePixelRatio;
        const app = new Application({
          width: 720,
          forceCanvas: true,
          height: 720 * ratio,
          transparent: !0,
          resolution: dpr
        });
        world.appendChild(app.view);
        // 将canvas 缩放为正常尺寸
        app.renderer.autoResize = true;
        app.renderer.resize(WorldWidth, WorldHeight);
        PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
        this.Config = {
          WORLD_WIDTH: 720,
          WORLD_HEIGHT: 720 * ratio,
          HALF_WORLD_WIDTH: 0.5 * 720,
          HALF_WORLD_HEIGHT: 0.5 * 720 * ratio,
          SCALE: WorldWidth / 720 * dpr,
          dpr,
          app
        };
        this.loadAssets();
      },
      // 预加载资源
      loadAssets () {
        Loader
          .add('background', '/static/image/stage.png')
          .add('arm', '/static/image/arm.png')
          .add('boybody', '/static/image/boybody.png')
          .add('btn', '/static/image/starBtn@2x.png')
          .add('mask', '/static/image/btnmask.png')
          .add('star', '/static/image/img_star_end.png')
          .add('starbg', '/static/image/starbg.png')
          .add('dropmask', '/static/image/dropmask@2x.png')
          .add('particle', '/static/image/particle.png')
          .add('smokeparticle', '/static/image/smokeparticle.png')
          .add('rule', '/static/image/rule@2x.png')
          .add('cardMask', '/static/image/mask.png')
          .add('prizeBg', '/static/image/prizeBg.png')
          .add('light', '/static/image/light.png');
        // tmp
        this.tmpArr = [];
        for (let i = 1, l = 10; i <= 10; i++) {
          this.tmpArr.push(`star_${i}`);
        }
        for (let t of this.tmpArr) {
          Loader.add(t, `/static/temppic/${t}.png`);
        }
        Loader.load(this.createStage);
      },
      // 绘制背景
      addBackground () {
        const bgGroup = new Container();
        const [bgTexture, starBgTexture] = [
          Loader.resources['background'].texture,
          Loader.resources['starbg'].texture
          ];
        let dropStars = [];
        for (let i of this.tmpArr) {
          dropStars.push(new Sprite(Loader.resources[i].texture))
        }
        const [bg, starBg] = [new Sprite(bgTexture), new Sprite(starBgTexture)];
        // 拉升背景图全屏
        bg.width = this.Config.WORLD_WIDTH;
        bg.height = this.Config.WORLD_HEIGHT;
        // 定义星空背景
        starBg.position.set(this.Config.HALF_WORLD_WIDTH, this.Config.HALF_WORLD_HEIGHT);
        starBg.anchor.set(0.5);
        bgGroup.addChild(bg);
        bgGroup.addChild(starBg);
        // 定义下垂星条
        dropStars.forEach((item, index) => {
          item.position.set(50 + index * 69, 160);
          item.anchor.set(0.5, 0);
          bgGroup.addChild(item);
        });
        dropStars[0].y = 100;
        dropStars[1].y = 140;
        dropStars[3].y = 170;
        dropStars[4].y = 170;
        dropStars[5].y = 170;
        dropStars[6].y = 170;
        dropStars[8].y = 140;
        dropStars[9].y = 100;

        this.worldStage.addChild(bgGroup);
        const flashTween = new TWEEN.Tween({
          alpha: 1
        }).to({
          alpha: 0.2
        }, 1000).easing(TWEEN.Easing.Cubic.Out).repeat(1e3).repeatDelay(1e3).yoyo(!0).onUpdate((param) => {
          starBg.alpha = param.alpha;
        });
        flashTween.start();
        const angleLeftTween = new TWEEN.Tween({
          rotation: -0.1
        }).to({
          rotation: 0.1
        }, 1000).easing(TWEEN.Easing.Sinusoidal.InOut).repeat(400).yoyo(!0).onUpdate((param) => {
           for (let item of [0, 1, 3, 4, 8]) {
             dropStars[item].rotation = param.rotation;
           }
        });
        angleLeftTween.start();
        const angleRightTween = new TWEEN.Tween({
          rotation: 0.1
        }).to({
          rotation: -0.1
        }, 1000).easing(TWEEN.Easing.Sinusoidal.InOut).repeat(600).yoyo(!0).onUpdate((param) => {
          for (let item of [2, 5, 6, 7, 9]) {
            dropStars[item].rotation = param.rotation;
          }
        });
        angleRightTween.start();
      },
      // 添加头部文字
      addHeaderText () {
        const textGp = new Container();
        const [titleStyle, labelStyle, numStyle] = [
          new TextStyle({
            fontFamily: 'PingFang SC',
            fontSize: 32,
            fill: ['#FFFFFF']
          }),
          new TextStyle({
            fontFamily: 'PingFang SC',
            fontSize: 26,
            fill: '#ffffff'
          }),
          new TextStyle({
            fontFamily: 'QuartzMdm',
            fontSize: 30,
            fill: '#ffffff',
            letterSpacing: 1
          })
        ];
        const title = new Text('星星点灯 电亮钱程', titleStyle);
        title.anchor.set(0.5);
        const [labelLf, labelRt] = [new Text('累计点亮', labelStyle), new Text('参与用户', labelStyle)];
        labelLf.anchor.set(0.5);
        labelRt.anchor.set(0.5);
        labelLf.x = -title.width * 0.5 - labelLf.width * 0.5;
        labelRt.x = title.width * 0.5 - labelRt.width * 0.5;
        let [lightNum, userNum] = [new Text(0, numStyle), new Text(0, numStyle)];
        lightNum.anchor.set(0, 0.5);
        userNum.anchor.set(0, 0.5);
        lightNum.x = labelLf.x + labelLf.width * 0.5 + 20;
        userNum.x = labelRt.x + labelRt.width * 0.5 + 20;
        for (let i of [title, labelLf, labelRt, lightNum, userNum]) {
          i.y = title.y + 60;
          textGp.addChild(i);
        }
        lightNum.text = 0;
        userNum.text = 0;
        this.lightNum = lightNum;
        this.userNum = userNum;
        textGp.position.set(this.Config.HALF_WORLD_WIDTH, 0);
        this.worldStage.addChild(textGp);
      },
      // 添加点灯按钮
      addStarBtn () {
        const btnGp = new Container();
        const [btnTexture, maskTexture] = [
          Loader.resources['btn'].texture,
          Loader.resources['mask'].texture
        ];
        const [btnSp, maskSp] = [
          new Sprite(btnTexture),
          new Sprite(maskTexture)
        ];
        btnSp.anchor.set(0.5);
        maskSp.anchor.set(0.5);
        maskSp.scale.set(2);
        maskSp.alpha = 0;
        btnGp.addChild(btnSp);
        btnGp.addChild(maskSp);
        btnGp.x = this.ruleBtn.x;
        btnGp.y = this.ruleBtn.y - 140;
        const [btnStyle, numStyle] = [new TextStyle({
          fontFamily: 'PingFang SC',
          fontSize: 26,
          fill: '#601986',
          lineHeight: 36,
          fontWeight: 'bold'
        }),
        new TextStyle({
          fontFamily: 'PingFang SC',
          fontSize: 15,
          fill: '#601986',
          lineHeight: 36
        })
        ];
        const btnName = new Text('点亮\n星灯', btnStyle);
        btnName.anchor.set(0.5);
        btnName.position.set(btnGp.x, btnGp.y - 4);
        const btnNum = new Text('(3次)', numStyle);
        btnNum.anchor.set(0.5);
        btnNum.position.set(btnName.x, btnName.y + btnName.height * 0.5 + 20);
        this.btnNum = btnNum;
        this.worldStage.addChild(btnGp);
        this.worldStage.addChild(btnName);
        this.worldStage.addChild(btnNum);
        // 绑定点灯按钮事件
        btnSp.interactive = !0;
        btnSp.buttonMode = !0;
        btnSp.on('pointerup', this.lightUp);
        // 点灯按钮tween
        let lightParam = {
          alpha: 0,
          scaleX: btnSp.scale.x,
          scaleY: btnSp.scale.y
        };
        this.lightRise = new TWEEN.Tween(lightParam);
        this.maskSp = maskSp;
        this.btnSp = btnSp;
      },
      // 添加规则按钮
      addRuleBtn () {
        const ruleTexture = Loader.resources['rule'].texture;
        const ruleBtn = new Sprite(ruleTexture);
        ruleBtn.anchor.set(0.5);
        ruleBtn.position.set(ruleBtn.width * 0.5 + 42, this.Config.WORLD_HEIGHT - 124);
        this.worldStage.addChild(ruleBtn);
        this.ruleBtn = ruleBtn;
        // 绑定规则按钮事件
        ruleBtn.interactive = !0;
        ruleBtn.buttonMode = !0;
        ruleBtn.on('pointerup', () => {
          // 打开规则弹窗
          this.toastVisible = !0;
          this.modalFlag = !0;
          this.$nextTick(() => {
            this.$refs.scrollTip && this.$refs.scrollTip._initComponent();
          });
        });
      },
      // 点灯Event
      lightUp () {
        // 关闭点击
        this.btnSp.interactive = !1;
        // 点击效果
        this.lightRise.to({
          alpha: 1,
          scaleX: this.btnSp.scale.x * 1.08,
          scaleY: this.btnSp.scale.y * 0.92
        }, 200).easing(TWEEN.Easing.Sinusoidal.Out).onUpdate((param) => {
          this.maskSp.alpha = param.alpha;
          this.btnSp.scale.x = param.scaleX;
          this.btnSp.scale.y = param.scaleY;
        }).repeat(1).yoyo(!0);
        this.lightRise.start();
        // 点击请求
        if (this.chanceNum >= 1) {
          this.requestLightup().then((e) => {
            // 点灯失败
            if (!e) {
              this.btnSp.interactive = !0;
            } else {
              // 点灯成功
              // 手臂抬起
              // 抬臂
              this.lightData.lightNum += 1;
              this.lightData.userNum += 1;
              this.lightNum.text = this.lightData.lightNum;
              this.userNum.text = this.lightData.userNum;

              this.chanceNum -= 1;
              this.btnNum.text = `(${this.chanceNum})次`;
              this.upArm = new Tween({
                rotation: -0.5
              });
              this.upArm.to({
                rotation: 0
              }, 800).easing(TWEEN.Easing.Cubic.Out).onUpdate((o) => {
                this.arm.rotation = o.rotation
              });
              this.upArm.start();
              this.lanternFly();
            }
          });
        } else {
          this.lightRise.onComplete(() => {
            this.btnSp.interactive = !0;
          });
        }
      },
      // 灯笼飞行
      lanternFly () {
        // 设置起飞
        this.lanternParam = {
          x: this.boyGp.x - 140,
          y: this.boyGp.y - 210,
          scale: 1,
          alpha: 1
        };
        // 灯笼起飞动画
        this.lanternUpTween = new TWEEN.Tween({
          y: this.boyGp.y - 160
        });
        this.lanternUpTween.to({
          y: this.boyGp.y - 210
        }, 800).easing(TWEEN.Easing.Back.Out).onUpdate((param) => {
          this.lantern.y = param.y;
        }).start().onComplete(() => {
          // 灯笼飞行动画
          this.lanternFlyTween = null;
          this.lanternFlyTween = new TWEEN.Tween(this.lanternParam);
          // 灯笼晃动动画
          this.lantern.rotation = 0;
          this.lanternShakeTween = new TWEEN.Tween({
            rotation: 0
          });
          const x = 100 + parseInt(560 * Math.random());
          const y = 200 + parseInt(200 * Math.random());
          // 设置飞行
          this.lanternFlyTween.to({
            x: x,
            y: y,
            alpha: 0.5,
            scale: this.lantern.scale.x * 0.01
          }, 4000).easing(TWEEN.Easing.Linear.None).onUpdate((param) => {
            this.lantern.position.set(param.x, param.y);
            this.lantern.scale.set(param.scale);
            this.lantern.alpha = param.alpha;
          }).start();
          // 设置晃动
          this.lanternShakeTween.to({
            rotation: 0.3
          }, 1500).easing(TWEEN.Easing.Cubic.Out).onUpdate((param) => {
            this.lantern.rotation = param.rotation;
          }).repeat(4).yoyo(!0).start();
          this.lanternFlyTween.onComplete(() => {
            this.particle.emitter.resetPositionTracking();
            this.particle.emitter.updateOwnerPos(x, y);
            this.brightFlag = !0;
            setTimeout(() => {
              this.particle.emitter.resetPositionTracking();
              this.particle.emitter.updateOwnerPos(this.Config.HALF_WORLD_WIDTH, 8000);
              setTimeout(() => {
                this.brightFlag = !1;
              }, 1800);
              setTimeout(() => {
                this.resetStage(x, y);
              }, 1000);
            }, 1000);
          });
        });
      },
      // 添加点亮的星星
      addStar () {
        const starTexture = Loader.resources['star'].texture;
        const star = new Sprite(starTexture);
        star.anchor.set(0.5);
        star.scale.set(0);
        this.starContainer.addChild(star);
        return star;
      },
      // 重置Stage
      resetStage (x, y) {
        let tmpStar = this.addStar();
        tmpStar.position.set(x, y);
        tmpStar.tween = new Tween({
          alpha: 0,
          scale: 0
        }).to({
          alpha: 1,
          scale: 1
        }, 800).easing(TWEEN.Easing.Bounce.Out).onUpdate((param) => {
          tmpStar.alpha = param.alpha;
          tmpStar.scale.set(param.scale);
        }).start();
        tmpStar.tween.chain(new Tween({
          scaleX: 1,
          scaleY: 1
        }).to({
            scaleX: 1.08,
            scaleY: 1.06
          }, 800).easing(TWEEN.Easing.Bounce.Out).onUpdate((param) => {
            tmpStar.scale.set(param.scaleX, param.scaleY);
          }).repeat(2000).yoyo(!0)
        );

        // 点亮星灯后重置动画
        tmpStar.tween.onComplete(() => {
          this.upArm = new Tween({
            rotation: 0
          });
          this.upArm.to({
            rotation: -0.5
          }, 800).easing(TWEEN.Easing.Cubic.Out).onUpdate((param) => {
            this.arm.rotation = param.rotation;
          }).start();
          this.lantern.scale.set(0.8);
          this.lantern.alpha = 0;
          this.lantern.rotation = 0;
          this.lantern.position.set(this.boyGp.x - 140, this.boyGp.y - 260);
          // 灯笼重置动画
          this.lanternResetTween = new TWEEN.Tween({
            y: this.boyGp.y - 260,
            rotation: 0,
            scale: 0.8,
            alpha: 0
          });
          this.lanternResetTween.to({
            y: this.boyGp.y - 160,
            alpha: 1,
            rotation: 0,
            scale: 1
          }, 800).easing(TWEEN.Easing.Cubic.Out).onUpdate((param) => {
            this.lantern.scale.set(param.scale);
            this.lantern.y = param.y;
            this.lantern.rotation = param.rotation;
            this.lantern.alpha = param.alpha;
          }).delay(200).start().onComplete(() => {
            this.btnSp.interactive = !0;
          });
        });
      },
      // 设置人物
      addBoy () {
        const boyGp = new Container();
        const [boyTexture, armTexture] = [Loader.resources['boybody'].texture,
        Loader.resources['arm'].texture];
        const [boy, arm] = [new Sprite(boyTexture), new Sprite(armTexture)];
        boy.anchor.set(0.5);
        arm.anchor.set(1);
        boyGp.addChild(boy);
        boyGp.addChild(arm);
        // 设置boy位置
        boyGp.position.set(this.Config.WORLD_WIDTH - boy.width * 0.5 - 40,
          this.Config.WORLD_HEIGHT - boy.height * 0.5 - 10);
        // 设置手臂位置
        arm.x = -4;
        arm.y = -40;
        arm.rotation = -0.5;
        this.worldStage.addChild(boyGp);
        let armParam = {rotation: arm.rotation};
        this.arm = arm;
        this.boyGp = boyGp;
      },
      // 添加灯笼
      addLantern () {
        const lanternTexture = Loader.resources['light'].texture;
        const lantern = new Sprite(lanternTexture);
        lantern.anchor.set(0.5);
        lantern.position.set(this.boyGp.x - 140, this.boyGp.y - 160);
        this.Config.app.stage.addChild(lantern);
        this.lantern = lantern;
      },
      // stage集
      createStage () {
        // 总容器
        this.worldStage = this.Config.app.stage;
        // 根据dpr 设置canvas缩放
        this.worldStage.scale.set(1 / this.Config.dpr * this.Config.SCALE);
        // 设置点亮星的粒子容器
        this.starContainer = new Container();
        this.addBackground();
        this.addBoy();
        this.addRuleBtn();
        this.addStarBtn();
        this.addLantern();
        this.addHeaderText();
        this.worldStage.addChild(this.starContainer);
        // 定义粒子效果
        this.particle = new BrightParticle(PIXI, this.worldStage, [Loader.resources['particle'].texture,
        Loader.resources['smokeparticle'].texture],
          {
            'alpha': {
              'start': 0.4,
              'end': 0
            },
            'scale': {
              'start': 0.9,
              'end': 0.4
            },
            'color': {
              'start': 'fffff',
              'end': 'f1ebaf'
            },
            'speed': {
              'start': 10,
              'end': 10
            },
            'startRotation': {
              'min': 0,
              'max': 360
            },
            'rotationSpeed': {
              'min': 0,
              'max': 0
            },
            'lifetime': {
              'min': 2,
              'max': 1.8
            },
            'blendMode': 'screen',
            'frequency': 0.01,
            'emitterLifetime': 0,
            'maxParticles': 180,
            'pos': {
              'x': 0.5,
              'y': 0.5
            },
            'addAtBack': false,
            'spawnType': 'circle',
            'spawnCircle': {
              'x': 0,
              'y': 0,
              'r': 50
            }
          });
        this.lightNum.text = this.lightData.lightNum;
        this.userNum.text = this.lightData.userNum;
        this.chanceNum = this.lightData.chanceNum;
        this.btnNum.text = this.lightData.btnNum;
        // 刷新帧事件
        this.Config.app.ticker.add((delta) => {
          this.Config.app.renderer.render(this.worldStage);
          TWEEN.update();
          this.brightFlag && this.particle.update();
        });
      },
      // 请求点灯
      async requestLightup () {
        try {
          const resData = await requestLight(
            {
              accountId: this.accountId,
              city: this.city
            }
          );
          if (resData.data.code === '200') {
            return true;
          } else {
            this.showToast(resData.data.text, !1);
            return false;
          }
        } catch (e) {
          console.log(e);
        }
      },
      showToast (mes, toastFlag) {
        this.toastMes = mes;
        this.modalFlag = !1;
        this.toastFlag = toastFlag;
        this.toastVisible = !0;
      },
      // 关闭modal
      closeToast () {
        this.toastVisible = !1;
      }
    },
    components: {
      toast,
      Header,
      Footer,
      Scroll,
      TipScroll
    }
  }
</script>

<style rel="stylesheet/stylus" lang="stylus">
  @import '../../../assets/css/mixin.styl';
.lu-wrap
  position relative
  height 100%
  .lightup-wrap
    font-family 'PingFang SC'
    position relative
    width 100%
    padding rpx(10)
    box-sizing border-box
    background-color #413198
    padding-bottom rpx(100)
    #lightbox
      font-family 'QuartzMdm'
      width rpx(730)
  .scrollH
    height "calc(100% - %s)" % rpx(140)!important
</style>
